package com.atguigu.asyncfilechannel;

import org.junit.jupiter.api.Test;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousFileChannel;
import java.nio.channels.CompletionHandler;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.Objects;
import java.util.concurrent.Future;

/**
 * className: AsyncFileChannelDemo
 * description:
 * date: 2023/3/10 0010-15:23
 * <p>
 * project: nio
 * package: com.atguigu.asyncfilechannel
 * email: 1085844536@qq.com
 * version:
 *
 * @author WangGuojian
 */
public class AsyncFileChannelDemo {

    @Test
    public void writeAsyncFileComplete() throws IOException {
        // 1.创建 AsynchronousFileChannel
        Path path = Paths.get(Objects.requireNonNull(AsyncFileChannelDemo.class.getClassLoader().getResource("02.txt")).getPath().substring(1));
        AsynchronousFileChannel fileChannel = AsynchronousFileChannel.open(path, StandardOpenOption.WRITE);

        // 2.创建 Buffer
        ByteBuffer buffer = ByteBuffer.allocate(1024);

        // 3.write 方法
        buffer.put("atguigujava".getBytes());
        buffer.flip();
        fileChannel.write(buffer, 0, buffer, new CompletionHandler<Integer, ByteBuffer>() {
            @Override
            public void completed(Integer result, ByteBuffer attachment) {
                buffer.clear();
                System.out.println("bytes written: " + result);
            }

            @Override
            public void failed(Throwable exc, ByteBuffer attachment) {

            }
        });

        System.out.println("writer over");
    }

    @Test
    public void writeAsyncFileFuture() throws IOException {
        // 1.创建 AsynchronousFileChannel
        Path path = Paths.get(Objects.requireNonNull(AsyncFileChannelDemo.class.getClassLoader().getResource("02.txt")).getPath().substring(1));
        AsynchronousFileChannel fileChannel = AsynchronousFileChannel.open(path, StandardOpenOption.WRITE);

        // 2.创建 Buffer
        ByteBuffer buffer = ByteBuffer.allocate(1024);

        // 3.write 方法
        buffer.put("atguigu".getBytes());
        buffer.flip();
        Future<Integer> future = fileChannel.write(buffer, 0);

        while (future.isDone()) {

        }

        buffer.clear();
        System.out.println("writer over");
    }

    @Test
    public void readAsyncFileChannelComplete() throws IOException {
        // 1.创建 AsynchronousFileChannel
        Path path = Paths.get(Objects.requireNonNull(AsyncFileChannelDemo.class.getClassLoader().getResource("02.txt")).getPath().substring(1));
        AsynchronousFileChannel fileChannel = AsynchronousFileChannel.open(path, StandardOpenOption.READ);

        // 2.创建 Buffer
        ByteBuffer buffer = ByteBuffer.allocate(1024);

        // 3.调用 channel 的 read 方法得到 future
        fileChannel.read(buffer, 0, buffer, new CompletionHandler<Integer, ByteBuffer>() {
            @Override
            public void completed(Integer result, ByteBuffer attachment) {
                System.out.println("result: " + result);

                buffer.flip();
                byte[] data = new byte[attachment.limit()];
                attachment.get(data);
                System.out.println(new String(data));
                buffer.clear();
            }

            @Override
            public void failed(Throwable exc, ByteBuffer attachment) {

            }
        });

    }

    @Test
    public void readAsyncFileChannelFuture() throws IOException {
        // 1.创建 AsynchronousFileChannel
        Path path = Paths.get(Objects.requireNonNull(AsyncFileChannelDemo.class.getClassLoader().getResource("02.txt")).getPath().substring(1));
        AsynchronousFileChannel fileChannel = AsynchronousFileChannel.open(path, StandardOpenOption.READ);

        // 2.创建 Buffer
        ByteBuffer buffer = ByteBuffer.allocate(1024);

        // 3.调用 channel 的 read 方法得到 future
        Future<Integer> future = fileChannel.read(buffer, 0);

        // 4.判断是否完成 isDone,返回 ture
        while (!future.isDone()) {

        }

        // 5.读取数据到 buffer 里面
        buffer.flip();
        // while (buffer.remaining() > 0) {
        //     System.out.println(buffer.get());
        // }
        byte[] data = new byte[buffer.limit()];
        buffer.get(data);
        System.out.println(new String(data));
        buffer.clear();
    }
}
